#include<event2/event.h>
#include<event2/bufferevent.h>
#include<event2/listener.h>
#include<string.h>
#include<stdio.h>
#include<unistd.h>

void readcb(struct bufferevent *bev, void *ctx)
{
    char buf[BUFSIZ];
    int ret = bufferevent_read(bev, buf, sizeof(buf));
    write(STDOUT_FILENO, buf, ret);
}

void writecb(struct bufferevent *bev, void *ctx)
{
    printf("send message to server!\n");
    return;
}

void eventcb(struct bufferevent *bev, short events, void *arg)
{
    if (events & BEV_EVENT_EOF)
    {
        printf("connection closed\n");  
    }
    else if(events & BEV_EVENT_ERROR)   
    {
        printf("some other error\n");
    }
    else if(events & BEV_EVENT_CONNECTED)
    {
        printf("已经连接服务器...\\(^o^)/...\n");
        return;
    }
    
    // 释放资源
    bufferevent_free(bev);
}

void read_terminal(evutil_socket_t fd, short what, void* arg)
{
    struct bufferevent * bev = (struct bufferevent *)arg;
    char buf[BUFSIZ];
    int ret = read(fd, buf, sizeof(buf));

    bufferevent_write(bev, buf, ret);
    return;
}

int main(int argc, char* argv[])
{
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8000);
    serverAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    int cfd = socket(AF_INET, SOCK_STREAM, 0);

    struct event_base * base = event_base_new();

    struct bufferevent * bev = bufferevent_socket_new(base, cfd, BEV_OPT_CLOSE_ON_FREE);

    bufferevent_setcb(bev, readcb, writecb, eventcb, NULL);

    bufferevent_enable(bev, EV_READ);

    bufferevent_socket_connect(bev, (struct sockaddr*)&serverAddr, sizeof(serverAddr));

    struct event * ev = event_new(base, STDIN_FILENO, EV_READ|EV_PERSIST, read_terminal, bev);

    event_add(ev, NULL);

    event_base_dispatch(base);
    
    event_free(ev);
    event_base_free(base);

    return 0;
}